import logging
import asyncio
import time
import kopf

import urllib3

# 需要import进来
from website import controller

urllib3.disable_warnings()


def bootstrap():
    kopf.configure(
        verbose=True,
    )

    logging.basicConfig(
        level=logging.DEBUG,
        format='%(asctime)s - [%(levelname)s] [%(name)s] %(message)s',
        datefmt="%Y-%m-%dT%H:%M:%S",
    )
    loop = asyncio.get_event_loop()
    loop.run_until_complete(
        # 运行这个方法，会触发controller中的被@kopf.on.startup()修饰的方法,会将Custom Resource Controller(Operator)注册到集群中
        # kopf.operator(
        #     clusterwide=False,
        #     priority=int(time.time() * 1000000),
        #     peering_name="custom_resources",
        #     namespaces=["cr-system"],
        # )
        kopf.operator(
            clusterwide=True,  # 监听集群所有命名空间下的自定义资源
            priority=int(time.time() * 1000000)
        )
    )
    """
    1. clusterwide=False
        含义：指定控制器的作用范围是否为 “集群级”。
        细节：
        当 clusterwide=False 时，控制器仅监听和处理 指定命名空间 内的自定义资源（由 namespaces 参数指定）。
        当 clusterwide=True 时，控制器会监听 整个集群 中所有命名空间的自定义资源（忽略 namespaces 参数）。
        使用场景：如果你的自定义资源是 “命名空间级”（CRD 中 scope: Namespaced），且只需管理特定命名空间的资源，设为 False；若需全局管理（如集群级资源 scope: Cluster），设为 True。
    2. priority=int(time.time() * 1000000)
        含义：设置控制器的 “优先级”，用于多控制器竞争同一资源时的冲突解决。
        细节：
        优先级是一个整数，值越大，优先级越高。
        当多个控制器（可能是同一类型的不同实例）同时监听同一资源时，Kubernetes 会选择优先级最高的控制器处理资源事件，避免冲突。
        这里用 int(time.time() * 1000000) 生成一个随时间递增的唯一值，确保每次启动的控制器实例有不同的优先级（常用于测试或动态部署场景）。
        注意：生产环境中通常会固定一个合理的优先级值（如 100），而非动态生成。
    3. peering_name="custom_resources"
        含义：指定 “peering 资源” 的名称，用于控制器之间的协调和信息共享。
        背景：Kopf 通过在 Kubernetes 中创建一个特殊的 ConfigMap（称为 “peering 资源”）来实现多个控制器实例之间的通信，例如：
        标记哪个控制器是 “领导者”（Leader Election）。
        同步资源处理的状态，避免重复操作。
        细节：peering_name 是这个 ConfigMap 的名称（默认值为 kopf-peering）。同一类控制器需使用相同的 peering_name 才能互相感知，不同类型的控制器应使用不同名称避免干扰。
    4. namespaces=["cr-system"]
        含义：指定控制器需要监听的命名空间列表。
        细节：
        仅当 clusterwide=False 时生效，此时控制器只会处理 ["cr-system"] 命名空间内的自定义资源。
        若需监听多个命名空间，可传入列表（如 namespaces=["ns1", "ns2"]）；若需监听所有命名空间，可设为 namespaces=None 并配合 clusterwide=True。
        作用：限制控制器的管理范围，提高效率（无需监听无关命名空间的资源事件）。
        总结
        这些参数共同定义了 Kopf 控制器的 “管理范围”“冲突处理策略” 和 “实例间协调方式”，核心目的是让控制器安全、高效地监听和处理 Kubernetes 中的自定义资源。根据你的业务需求（如资源是否集群级、是否需要多实例部署等），可以调整这些参数的值。
    """

    return 0


if __name__ == "__main__":
    try:
        bootstrap()
    except KeyboardInterrupt:
        print("CustomResources stopped by user.")
    except Exception as e:
        print(f"CustomResources failed with error: {e}")
        exit(1)
